package com.moli.iov.admin.service.impl;

import com.moli.iov.admin.model.vo.res.VehicleAlarmStatusVo;
import com.moli.iov.admin.model.vo.res.VehicleAuthVo;
import com.moli.iov.admin.model.vo.res.VehicleCommandVo;
import com.moli.iov.admin.model.vo.res.VehicleDetailVo;
import com.moli.iov.admin.service.VehicleBaseService;
import com.moli.iov.alarm.model.dto.req.AlarmInfoReqDto;
import com.moli.iov.alarm.model.dto.res.AlarmDetailDto;
import com.moli.iov.alarm.remote.IAlarmRemoteService;
import com.moli.iov.base.enums.DictTypeTag;
import com.moli.iov.base.model.dto.req.*;
import com.moli.iov.base.model.dto.res.VehicleBaseAuthResDto;
import com.moli.iov.base.model.dto.res.VehicleBaseTboxResDto;
import com.moli.iov.base.model.po.VehicleFence;
import com.moli.iov.base.remote.*;
import com.moli.iov.down.model.po.VehicleParam;
import com.moli.iov.down.remote.IVehicleParamRemoteService;
import com.moli.iov.enums.UserTypeEnum;
import com.moli.iov.protocol.model.realtime.RealTimeInfo;
import com.moli.iov.protocol.model.realtime.RealTimeInfoReq;
import com.moli.iov.protocol.util.RealTimeInfoUtil;
import com.moli.iov.real.model.res.VehicleStatusDto;
import com.moli.iov.real.service.IRealService;
import com.moli.iov.rest.RestResponse;
import com.moli.iov.sys.model.po.Company;
import com.moli.iov.sys.remote.ICompanyRemoteService;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import com.moli.iov.util.CommonUtils;
import com.moli.iov.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

/**
 * The type Vehicle base service.
 *
 * @author whl
 * @date 2019-09-16 19:24:47
 */
@Service
@Slf4j
public class VehicleBaseServiceImpl implements VehicleBaseService {

  @Reference(group = "${service.group}", check = false,timeout = 180000)
  private IVehicleBaseRemoteService iVehicleBaseRemoteService;
  @Reference(group = "${service.group}", check = false)
  private IVehicleAttentionRemoteService attentionRemoteService;
  @Reference(group = "${service.group}", check = false)
  private IVehicleFollowGroupRemoteService followGroupRemoteService;
  @Reference(group = "${service.group}", check = false)
  private IVehicleTboxRemoteService iVehicleTboxRemoteService;
  @Reference(group = "${service.group}", check = false)
  private IRealService iRealService;
  @Reference(group = "${service.group}", check = false)
  private IDictDataRemoteService dictDataService;
  @Reference(group = "${service.group}", check = false)
  private IVehicleParamRemoteService vehicleParamService;
  @Reference(group = "${service.group}", check = false)
  private ICompanyRemoteService iCompanyRemoteService;
  @Reference(group = "${service.group}", check = false)
  private IAlarmRemoteService alarmRemoteService;
  @Reference(group = "${service.group}", check = false)
  private IAlarmEquipmentRecordRemoteService alarmEquipmentRecordRemoteService;
  @Reference(group = "${service.group}", check = false)
  private IVehicleBaseAuthRemoteService vehicleBaseAuthRemoteService;
  @Reference(group = "${service.group}", check = false)
  private IVehicleFenceRemoteService vehicleFenceRemoteService;

  @Override
  public RestResponse queryAttentionVehicleGraphics(VehicleGraphicsQueryListReqDto reqDto) {
    return iVehicleBaseRemoteService.queryAttentionVehicleGraphics(reqDto);
  }

  @Override
  public RestResponse queryAttentionGroup(Long userId){
    return iVehicleBaseRemoteService.queryAttentionGroup(userId);
  }

  @Override
  public RestResponse listVehicleGraphicsQueryListRes(VehicleGraphicsQueryListReqDto reqDto) {
    return iVehicleBaseRemoteService.listVehicleGraphicsQueryListRes(reqDto);
  }

  @Override
  public RestResponse listVehicleQueryListRes(QueryVehicleBaseListReqDto reqDto) {
    return iVehicleBaseRemoteService.listVehicleQueryListRes(reqDto);
  }

  @Override
  public RestResponse queryAttentionVehicleList(QueryVehicleBaseListReqDto reqDto){
    return iVehicleBaseRemoteService.queryAttentionVehicleList(reqDto);
  }

  @Override
  public RestResponse saveVehicleBase(VehicleBaseReqDto dto) {
    if (dto.getSysUserType().intValue()== UserTypeEnum.COMPANY.getFlag()){
      dto.setCompanyId(dto.getSysCompanyId());
    }
    //校验企业
    Company company = iCompanyRemoteService.companyValid(dto.getCompanyId());
    dto.setCompanyName(company.getCompanyName());
    return iVehicleBaseRemoteService.saveVehicleBase(dto);
  }

  @Override
  public RestResponse updateVehicleBase(VehicleBaseReqDto dto) {
    if (dto.getSysUserType().intValue()== UserTypeEnum.COMPANY.getFlag()){
      dto.setCompanyId(dto.getSysCompanyId());
    }
    //校验企业
    Company company = iCompanyRemoteService.companyValid(dto.getCompanyId());
    dto.setCompanyName(company.getCompanyName());
    return iVehicleBaseRemoteService.updateVehicleBase(dto);
  }

  @Override
  public RestResponse saveVehicleAttention(VehicleAttentionReqDto dto) {
    /**
     * 批量添加
     */
    return attentionRemoteService.saveBatchVehicleAttention(dto);
  }

  @Override
  public RestResponse updateVehicleAttention(UpdateVehicleAttentionReqDto dto) {
    /**
     * 批量添加
     */
    return attentionRemoteService.updateVehicleAttention(dto);
  }

  @Override
  public RestResponse saveVehicleFollowGroup(VehicleFollowGroupReqDto dto){
    return followGroupRemoteService.save(dto);
  }

  @Override
  public RestResponse<VehicleDetailVo> getVehicleDetail(String vin) throws Exception {
    log.info("[查询车辆信息][入参：{}]", vin);

    if (StringUtils.isEmpty(vin)) {
      log.error("[查询车辆信息][vin为 null]");
      return RestResponse.failure("参数不能为空!");
    }
    //获取车辆基础数据
    VehicleBaseTboxQueryReqDto dto = new VehicleBaseTboxQueryReqDto();
    dto.setVin(vin);
    VehicleBaseTboxResDto tboxByVin = iVehicleTboxRemoteService.getVehicleTboxByVin(vin);
    //获取车辆是否在线
    Boolean onlineState = null;
    RestResponse<Boolean> onlineRes = iRealService.isOnline(vin);
    if (onlineRes != null) {
      onlineState = onlineRes.getData();
    }
    //获取车辆实时数据
    RealTimeInfoReq realTimeInfoDto = null;
    RestResponse<RealTimeInfo> realTimeInfoDtoRes = iRealService.getRealTime(vin);
    RealTimeInfo info = null;
    if (realTimeInfoDtoRes != null ) {
      info = realTimeInfoDtoRes.getData();
      if (info != null) {
        realTimeInfoDto = realTimeInfoDtoRes.getData().getRealTimeInfoReq();
      }
    }
    List<DictTypeTag> tagList = new ArrayList<>();
    tagList.add(DictTypeTag.BRAND);
    tagList.add(DictTypeTag.VEHICLE_SERIES);
    tagList.add(DictTypeTag.VEHICLE_TYPE);
    tagList.add(DictTypeTag.SUPPLIERNAME);
    Map<String, Map<String, String>> dictMap = dictDataService.getDictMaps(tagList);
    VehicleParam param = vehicleParamService.getVehicleParamByVin(vin);

    RestResponse<Date> lastTime = iRealService.getLastReportTime(vin);
    
    VehicleDetailVo detail = new VehicleDetailVo(tboxByVin, realTimeInfoDto, onlineState, dictMap, param ,info);

    //  vehicleFenceBindingRemoteService.listVehicleFenceByVin
    detail = setFenceBinding(detail);
    detail = setAlarmStatus(detail);
    detail = setAuthStatus(detail,tboxByVin);
    detail = setRealOdo(detail);
    if(detail!=null && lastTime.flag && lastTime.getData()!=null){
      detail.setReportDate(lastTime.getData());
    }

    return RestResponse.success(detail);
  }

  private VehicleDetailVo setRealOdo(VehicleDetailVo detail){
    detail.getVin();
    List<String> list = new ArrayList<>();
    list.add(detail.getVin());
    RestResponse<Map<String, VehicleStatusDto>> voi = iRealService.getVehicleStatusByVin(list);
    if(voi!=null && voi.getData()!=null && StringUtil.isNotBlank(detail.getVin())){
      VehicleStatusDto res = voi.getData().get(detail.getVin());
      if(res!=null){
        detail.setRealOdo(res.getOdo());
      }
    };

    return detail;
  }

  //  vehicleFenceBindingRemoteService.listVehicleFenceByVin

  private VehicleDetailVo setFenceBinding(VehicleDetailVo detail){
    String fenceNames = null;
    String vin  = detail.getVin();
    List<VehicleFence> res = vehicleFenceRemoteService.listVehicleFenceByVin(vin);
    StringBuffer sb = new StringBuffer();
    if(res!=null && res.size()>0){
      for (VehicleFence re : res) {
        if(re!=null && StringUtil.isNotBlank(re.getFenceName())){
          sb.append(re.getFenceName()+",");
        }
      }
      if(sb.length()>0){
        fenceNames = sb.substring(0,sb.length()-1);
      }
    }
    if(fenceNames==null){
      fenceNames = "--";
    }
    detail.setFenceNames(fenceNames);
    return detail;
  }
  public VehicleDetailVo setAuthStatus(VehicleDetailVo detail,VehicleBaseTboxResDto baseTbox){

      String vin = detail.getVin();
      VehicleBaseAuthReqDto dto = new VehicleBaseAuthReqDto();
      dto.setVin(vin);
      RestResponse<VehicleBaseAuthResDto> auth = vehicleBaseAuthRemoteService.getVehicleBaseAuth(dto);
      VehicleAuthVo authVo = new VehicleAuthVo();
      if(auth!=null && auth.flag){
          CommonUtils.copyProperties(auth.getData(),authVo);
      }
      if(baseTbox!=null){
        CommonUtils.copyProperties(baseTbox,authVo);
      }
      detail.setAuth(authVo);
      return detail;
  }

  private VehicleDetailVo setAlarmStatus(VehicleDetailVo detail){

      VehicleAlarmStatusVo status = new VehicleAlarmStatusVo();

      String vin  = detail.getVin();
      AlarmDetailDto alarmDetailDto = getVehicleAlarmStatus(detail.getVin());
      CommonUtils.copyProperties(alarmDetailDto, status);

      RestResponse<Boolean> isChangeExcep = alarmEquipmentRecordRemoteService.hasAlarmEquipmentRecordByVin(vin);
      if(isChangeExcep!=null && isChangeExcep.flag){
          Boolean isChangeEx = isChangeExcep.getData();
          status.setIsChangeExcep(isChangeEx?1:0);
      }

      detail.setAlarmStatus(status);
      return detail;
  }

  private AlarmDetailDto getVehicleAlarmStatus(String vin ){
    AlarmInfoReqDto alarmInfoReq = new AlarmInfoReqDto();
    alarmInfoReq.setVin(vin);
    RestResponse<AlarmDetailDto> res = alarmRemoteService.getAlarmDetailByVin(alarmInfoReq);
    if(res!=null && res.flag){
      return res.getData();
    }
    return null;

  }


  @Override
  public RestResponse deleteVehicleAttention(VehicleAttentionReqDto dto) {
    return  attentionRemoteService.deleteBatchVehicleAttention(dto);
  }

  @Override
  public RestResponse deleteVehicleFollowGroup(VehicleFollowGroupReqDto dto) {
    return  followGroupRemoteService.delete(dto);
  }

  @Override
  public RestResponse<VehicleCommandVo> getVehicleCommandList(String vin) {
    List<String> strings = new ArrayList<>();
    strings.add(vin);
    RestResponse<Map<String, VehicleStatusDto>> res = iRealService.getVehicleStatusByVin(strings);
    if (res != null && !CollectionUtils.isEmpty(res.getData()) && res.getData().get(vin) != null) {
      VehicleCommandVo vehicleCommandVo = new VehicleCommandVo();
      VehicleStatusDto vehicleStatusDto = res.getData().get(vin);
      vehicleCommandVo.setVin(vehicleStatusDto.getVin());
      vehicleCommandVo.setDynamicState(vehicleStatusDto.getDynamicState().getV());
      vehicleCommandVo.setExtendLeasing(vehicleStatusDto.getExtendLeasing().getV());
      vehicleCommandVo.setPhysicalKeyState(vehicleStatusDto.getPhysicalKeyState().getV());
      return RestResponse.success(vehicleCommandVo);
    }else{
      return RestResponse.failure("车辆状态不存在");
    }
  }
}
